﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using BlogApp.Data.Models;
using BlogApp.Data.Service;
using BlogApp.WP8.Resources;
using BlogApp.WP8.Utils;
using GalaSoft.MvvmLight.Command;
using Microsoft.Practices.ServiceLocation;

namespace BlogApp.WP8.ViewModel
{
    public class SearchViewModel : DataViewModel
    {

        public RelayCommand<string> SearchPostWithQuery { get; private set; }
        public RelayCommand LoadMoreItems { get; private set; }


        private PostResult _searchResults = new PostResult();
        public PostResult SearchResults
        {
            get { return _searchResults; }
            set { _searchResults = value; RaisePropertyChanged("SearchResults"); }
        }

        private KeyValuePair<string, int> _queryPageIndex;
        private string _searchQuery = string.Empty;

        private bool _searchInActiveCategory;
        public bool SearchInActiveCategory
        {
            get { return _searchInActiveCategory; }
            set { _searchInActiveCategory = value; RaisePropertyChanged("SearchInActiveCategory"); }
        }

        private string _searchResultString;
        public string SearchResultString
        {
            get { return _searchResultString; }
            set { _searchResultString = value; RaisePropertyChanged("SearchResultString"); }
        }

        public SearchViewModel()
        {
            SearchPostWithQuery = new RelayCommand<string>(searchPostWithQuery);
            LoadMoreItems = new RelayCommand(loadMoreItems);
        }

        private async void searchPostWithQuery(string query)
        {
            if (!DataService.Instance.IsOffline)
            {
                Debug.WriteLine("SearchViewModel.cs | searchPostWithQuery | Query: {0}", query);
                IsLoading = true;
                _searchQuery = query;

                var searchResults = await DataService.Instance.GetPostsByQueryAsync(_searchQuery);

                if (SearchInActiveCategory)
                {
                    if (searchResults.Posts != null)
                    {
                        try
                        {
                            var categoryTitle = ServiceLocator.Current.GetInstance<CategoryViewModel>().SelectedCategory.Title;
                            IEnumerable<IGrouping<string, Post>> filteredPostst = searchResults.Posts.GroupBy(e => e.Categories.FirstOrDefault().Title);

                            var postForCategory = filteredPostst.FirstOrDefault(e => e.Key == categoryTitle);
                            if (postForCategory != null)
                            {
                                searchResults.Posts = new ObservableCollection<Post>(postForCategory.ToList());
                                SearchResults = searchResults;
                            }
                            else
                            {
                                SearchResults = new PostResult() {Posts = new ObservableCollection<Post>()};
                                SearchResultString = string.Format(AppResources.SearchSingleCategoryNoResults, categoryTitle);
                            }
                            SearchResultString = string.Format(AppResources.SearchSingleCategory, categoryTitle);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                        SearchResultString = "Fehler bei der Suche";
                        }


                    }
                }
                else
                {
                    if (DataService.Instance.IsOffline)
                    {
                        MessageBox.Show(AppResources.MessageBoxErrorSearch);
                    }
                    else
                    {
                        SearchResults = searchResults.Posts != null ? searchResults : new PostResult();
                        SearchResultString = string.Format(AppResources.SearchAllCategories, SearchResults.CountTotal);
                    }
                }

                IsLoading = false;
            }
            else
            {
                MessageBox.Show(AppResources.MessageBoxErrorSearch);
            }
        }


        private async void loadMoreItems()
        {
            if (!DataService.Instance.IsOffline)
            {
                IsLoading = true;
                int pageIndex = 2; // set to 2 as it wont meet the condition to increment the pageIndex for the first run

                if (_queryPageIndex.Key != null && _queryPageIndex.Key == _searchQuery)
                {
                    pageIndex = _queryPageIndex.Value;
                    pageIndex++;
                }

                _queryPageIndex = new KeyValuePair<string, int>(_searchQuery, pageIndex);
                if (pageIndex < SearchResults.Pages)
                {
                    var moreItems = await DataService.Instance.GetPostsByQueryAsync(_searchQuery, pageIndex);

                    if (moreItems.Posts != null)

                        if (SearchInActiveCategory)
                        {
                            var categoryTitle = ServiceLocator.Current.GetInstance<CategoryViewModel>().SelectedCategory.Title;
                            IEnumerable<IGrouping<string, Post>> filteredPostst = moreItems.Posts.GroupBy(e => e.Categories.FirstOrDefault().Title);

                            var postForCategory = filteredPostst.FirstOrDefault(e => e.Key == categoryTitle);

                            if (postForCategory != null)
                                SearchResults.Posts.AddRange(postForCategory);
                        }
                        else
                        {
                            SearchResults.Posts.AddRange(moreItems.Posts);

                        }
                }

                IsLoading = false;
            }
        }

        public override void Cleanup()
        {
            SearchInActiveCategory = false;
            SearchResultString = string.Empty;
            SearchResults = new PostResult() { Posts = new ObservableCollection<Post>() };

            base.Cleanup();
        }
    }
}